package game;

import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.util.Random;

public class MatrixManager {
	
	private static MatrixManager instance;
	public MatrixCell[][] matrixF, matrixS, matrixR;
	int type;
	private Random random = new Random(); 
	
	public static MatrixManager getInstace()
	{
		if(instance == null)
			instance = new MatrixManager();
			
		return instance;
	}
	
	
	public void draw(Graphics2D g2d)
	{
		for (int x = 0; x < type; x++)
			for (int y = 0; y < type; y++)
			{
				if(matrixF != null)
					if(matrixF.length == 1)
						matrixF[0][0].draw(g2d);
					else
						matrixF[x][y].draw(g2d);
				matrixS[x][y].draw(g2d);
				if(matrixR.length == 1)
					matrixR[0][0].draw(g2d);
				else
					matrixR[x][y].draw(g2d);
			}
	}
	
	public void CriarMatrix(ParColchete par1, ParColchete par2, ParColchete par3)
	{
		matrixF = matrixS = matrixR = null;
		type = MatrixType.getMatrixType().length;
		
		Point2D sizeBloco = new Point2D.Double(60, 25);
		Point2D aumento;
		if(type == 2)
			aumento = new Point2D.Double(10, 23);
		else
			aumento = new Point2D.Double(10, 33);
		
		switch(MatrixOperation.getTypeOperation())
		{
			case SOMAR:
				matrixF = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixS = GenerateMatrix(par2.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(par3.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				break;
			case MULTIPLICAR_MATRIZES:
				matrixF = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixS = GenerateMatrix(par2.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(par3.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				break;
			case SUBTRAIR:
				matrixF = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixS = GenerateMatrix(par2.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(par3.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				break;
			case OPOSTA:
				matrixF = null;
				matrixS = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(par2.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				break;
			case MULTIPLICAR_NUMERO:
				matrixF = new MatrixCell[1][1];
				Point2D pos;
				if(type == 2)
					pos = new Point2D.Double(140, 265);
				else
					pos = new Point2D.Double(100, 255);
				
				matrixF = GenerateMatrix(pos, aumento, sizeBloco, 1);
				matrixS = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(par2.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				break;
				
			case TRANSPOSTA:
				matrixF = null;
				matrixS = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(par2.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				break;	
				
			case DETERMINANTE:
				matrixR = new MatrixCell[1][1];
				Point2D pos2;
				if(type == 2)
					pos2 = new Point2D.Double(470, 265);
				else
					pos2 = new Point2D.Double(550, 255);
				
				matrixS = GenerateMatrix(par1.getColcheteESQ().getPosition(), aumento, sizeBloco, type);
				matrixR = GenerateMatrix(pos2, aumento, sizeBloco, 1);
				break;
		}
	}
	
	public MatrixCell[][] GenerateMatrix(Point2D pos, Point2D aumento, Point2D sizeBloco, int sizeMatrix)
	{
		MatrixCell[][] generatedMatrix = new MatrixCell[sizeMatrix][sizeMatrix];
		pos = new Point2D.Double(pos.getX() + aumento.getX(), pos.getY() + aumento.getY());
		
		for (int x = 0; x < sizeMatrix; x++)
		{
			for (int y = 0; y < sizeMatrix; y++)
			{
				generatedMatrix[x][y] = new MatrixCell("/images/MatrixCell.png", new Point2D.Double(pos.getX() + ((sizeBloco.getX() + 5) * y), pos.getY() + ((sizeBloco.getY() + 5) * x)), sizeBloco, 
													   new Point2D.Double(0, 0), new Point2D.Double(5, 5), true);
			}
		}
		
		return generatedMatrix;
	}
	
	public void AddNaMatrizResult(double matriz[][])
	{
		if(matriz.length != 1)
		{
			for(int x = 0; x < type; x++)
				for(int y = 0; y < type; y++)
					matrixR[x][y].value = "" +  matriz[x][y];
		}
		else
		{
			matrixR[0][0].value = "" +  matriz[0][0];
		}
	
	}
	
	public void RandomizarMatriz()
	{
		if(matrixS != null)
			for(int x = 0; x < matrixS.length; x++)
				for(int y = 0; y < matrixS.length; y++)
					matrixS[x][y].value = (-99 +random.nextInt(198)) + "." + random.nextInt(99);
		if(matrixF != null)
			for(int x = 0; x < matrixF.length; x++)
				for(int y = 0; y < matrixF.length; y++)
					matrixF[x][y].value = (-99 +random.nextInt(198)) + "." + random.nextInt(99);
	}
	
	public double[][] ReturnMatrizEmDouble(MatrixCell matriz[][])
	{
		double matrizDouble[][] = new double[matriz.length][matriz.length];
		
		for(int x = 0; x < matriz.length; x++)
			for(int y = 0; y < matriz.length; y++)
				matrizDouble[x][y] = Double.parseDouble(matriz[x][y].value);
		
		return matrizDouble;
	}
}
